﻿using ApiConceptsFramework.Concepts.Properties;
using ApiConceptsFramework.Contract;
using FluentAssertions;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;

namespace test.ApiConceptsFramework.Concepts.Properties
{
	[TestFixture]
	public class NumberOfMembersWithSamePrefixTests
	{
// ReSharper disable UnusedMember.Local
// ReSharper disable InconsistentNaming
		class TestClass
		{
			public int addField = 0;
			public void AddMethod1() { }
			public void AddMethod1(string value) { } //overloads should not be counted for visual studio
			public void AddMethod2() { }
			public string AddProperty1 { get; set; }
			public string AddProperty2 { get; private set; }
			
			public static void AddMethodStatic1() { } //static methods should not be counted together with instance methods 
			public static void AddMethodStatic2() { }

			public void ManyMethodsWithSamePrefix01() { }
			public void ManyMethodsWithSamePrefix02() { }
			public void ManyMethodsWithSamePrefix03() { }
			public void ManyMethodsWithSamePrefix04() { }
			public void ManyMethodsWithSamePrefix05() { }
			public void ManyMethodsWithSamePrefix06() { }
			public void ManyMethodsWithSamePrefix07() { }
			public void ManyMethodsWithSamePrefix08() { }
			public void ManyMethodsWithSamePrefix09() { }
			public void ManyMethodsWithSamePrefix10() { }
			public void ManyMethodsWithSamePrefix11() { }
			public void ManyMethodsWithSamePrefix12() { }
		}
// ReSharper restore InconsistentNaming		
// ReSharper restore UnusedMember.Local

		[Test, Sequential]
		public void Complexity_equals_half_of_before_members_with_same_prefix(
			[Values("addField", "AddMethod2", "AddProperty2", "AddMethodStatic2")] string member, 
			[Values(0.0f, 1.0f, 2.0f, 0.5f)] float expectedResult)
		{
			//Arrange
			var measurableProperty = new NumberOfMembersWithSamePrefix();
			var method = typeof(TestClass).GetMember(member).First();
			
			//Act
			var target = new MeasurableTarget { Type = typeof(TestClass), Member = method };
			var result = measurableProperty.CalculateComplexity(target, IDE.VisualStudioOrSimilar);

			//Assert
			result.Should().Be(expectedResult);
			Console.WriteLine("Complexity of " + member + " = " + result);
		}

		[Test]
		public void No_suggestions_are_made_for_few_members()
		{
			//Arrange
			var measurableProperty = new NumberOfMembersWithSamePrefix();
			var method = typeof(TestClass).GetMember("AddMethod1").First();

			//Act
			var target = new MeasurableTarget { Type = typeof(TestClass), Member = method };
			var result = measurableProperty.GetSuggestions(target, IDE.VisualStudioOrSimilar);

			//Assert
			result.Should().BeEmpty();
		}

		[Test]
		public void Suggestion_is_made_for_many_members()
		{
			//Arrange
			var measurableProperty = new NumberOfMembersWithSamePrefix();
			var method = typeof (TestClass).GetMember("ManyMethodsWithSamePrefix11").First();

			//Act
			var target = new MeasurableTarget { Type = typeof(TestClass), Member = method };
			var result = measurableProperty.GetSuggestions(target, IDE.VisualStudioOrSimilar).ToList();

			//Assert
			result.Should().HaveCount(1);
			Console.WriteLine(result.First());
		}
	}
}
